package com.zhuhao.threaddemo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 如果多个线程对同一个共享数据进行访问而不采取同步操作的话，那么操作的结果是不一致的。
 * 1000 个线程同时对 cnt 执行自增操作，操作结束之后它的值有可能小于 1000。
 *
 * @Author zhuhao
 * @Date 2022/5/31 16:17
 * @desc
 */
public class ThreadUnsafeExample {

    private int cnt = 0;

    public void add() {
        cnt++;
    }

    public int getCnt() {
        return cnt;
    }

    public static void main(String[] args) throws InterruptedException {
        final int threadSize = 1000;
        //倒数的门栓,似乎有一点“三二一，芝麻开门”的感觉.CountDownLatch的作用也是如此，在构造CountDownLatch的时候需要传入一个整数n，
        // 在这个整数“倒数”到0之前，主线程需要等待在门口，而这个“倒数”过程则是由各个执行线程驱动的，每个线程执行完一个任务“倒数”一次
        ThreadUnsafeExample example = new ThreadUnsafeExample();
        CountDownLatch countDownLatch = new CountDownLatch(threadSize);
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < threadSize; i++) {
            executorService.execute(() -> {
                example.add();
                //用于使计数器减一
                countDownLatch.countDown();
            });
        }
        //调用该方法的线程处于等待状态，countDownLatch的计数器为0时则被唤醒
        countDownLatch.await();
        executorService.shutdown();
        System.out.println(example.getCnt());
    }
}
